package com.example.chengzhengwei;

import android.app.Application;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;

import com.example.chengzhengwei.utils.HexUtils;
import com.example.chengzhengwei.utils.SpectrophotometerProtocol;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class SerialApp extends Application {
    private static final String TAG = "SerialApp";
    private TtySerialPortHelper mSerialHelper;
    private final Handler mMainHandler = new Handler(Looper.getMainLooper());
    private final List<Byte> mDataBuffer = new ArrayList<>(); // 数据缓冲区
    // 最大帧长度限制（防止缓冲区溢出）
    private static final int MAX_FRAME_SIZE = 1024;

    // 状态监听器
    public interface SerialStateListener {
        void onSerialConnected();
        void onSerialDisconnected();
        void onSerialError(Exception e);
    }

    private SerialStateListener mStateListener;
    private SerialReadCallback mActiveReadCallback;

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public void onTerminate() {
        super.onTerminate();
        releaseSerialConnection();
    }

    public void initSerialConnection() {
        Log.i(TAG, "Initializing serial connection...");
        if (mSerialHelper != null && mSerialHelper.isOpen()) {
            return; // 已连接则不再初始化
        }

        mSerialHelper = new TtySerialPortHelper(this);

        // 设置数据接收监听器
        mSerialHelper.setOnDataReceivedListener(data -> {
            if (data != null && data.length > 0 && mActiveReadCallback != null) {
                processReceivedData(data, mActiveReadCallback);
            }
        });

        mSerialHelper.openAsync(new TtySerialPortHelper.SerialOpenCallback() {
            @Override
            public void onOpenSuccess() {
                Log.i(TAG, "Serial port connected");
                notifySerialConnected();
            }

            @Override
            public void onOpenError(Exception e) {
                Log.e(TAG, "Serial port connection failed", e);
                notifySerialError(e);

                // 自动重连机制（每5秒尝试一次）
                mMainHandler.postDelayed(() -> initSerialConnection(), 5000);
            }
        });
    }

    public void releaseSerialConnection() {
        Log.i(TAG, "Releasing serial connection...");
        if (mSerialHelper != null) {
            if (mSerialHelper.isOpen()) {
                notifySerialDisconnected();
            }
            mSerialHelper.shutdown();
            mSerialHelper = null;
        }

        // 清空缓冲区和回调
        synchronized (mDataBuffer) {
            mDataBuffer.clear();
        }
        mActiveReadCallback = null;
    }

    public TtySerialPortHelper getSerialHelper() {
        return mSerialHelper;
    }

    public void setSerialStateListener(SerialStateListener listener) {
        mStateListener = listener;
    }

    private void notifySerialConnected() {
        mMainHandler.post(() -> {
            if (mStateListener != null) {
                mStateListener.onSerialConnected();
            }
        });
    }

    private void notifySerialDisconnected() {
        mMainHandler.post(() -> {
            if (mStateListener != null) {
                mStateListener.onSerialDisconnected();
            }
        });
    }

    private void notifySerialError(Exception e) {
        mMainHandler.post(() -> {
            if (mStateListener != null) {
                mStateListener.onSerialError(e);
            }
        });
    }

    // 安全写入方法（主线程调用）
    public void safeWrite(byte[] data, SerialWriteCallback callback) {
        Log.d(TAG,"=>"+HexUtils.printHexV2(data));
        if (mSerialHelper == null || !mSerialHelper.isOpen()) {
            if (callback != null) {
                callback.onWriteError(new IOException("Serial not initialized"));
            }
            return;
        }

        mSerialHelper.writeAsync(data, new TtySerialPortHelper.SerialWriteCallback() {
            @Override
            public void onWriteComplete(int bytesWritten) {
                if (callback != null) {
                    mMainHandler.post(() -> callback.onWriteComplete(bytesWritten));
                }
            }

            @Override
            public void onWriteError(Exception e) {
                if (callback != null) {
                    mMainHandler.post(() -> callback.onWriteError(e));
                }
            }
        });
    }

    // 开始接收数据（设置回调）
    public void startReading(SerialReadCallback callback) {
        if (mSerialHelper == null || !mSerialHelper.isOpen()) {
            Log.w(TAG, "Cannot start reading: serial not open");
            return;
        }

        // 设置活动回调
        mActiveReadCallback = callback;

        // 清空之前的缓冲区
        synchronized (mDataBuffer) {
            mDataBuffer.clear();
        }
    }

    // 停止接收数据
    public void stopReading() {
        mActiveReadCallback = null;
    }

    /**
     * 处理接收到的数据，处理不完整帧的情况
     *
     * @param data 接收到的原始数据
     * @param callback 数据回调接口
     */
    private void processReceivedData(byte[] data, SerialReadCallback callback) {
        synchronized (mDataBuffer) {
            // 1. 将新数据添加到缓冲区
            for (byte b : data) {
                mDataBuffer.add(b);
            }

            // 2. 检查缓冲区是否超过最大限制
            if (mDataBuffer.size() > MAX_FRAME_SIZE) {
                Log.w(TAG, "Buffer overflow, clearing buffer");
                mDataBuffer.clear();
                return;
            }

            // 3. 尝试在缓冲区中查找完整帧
            while (true) {
                // 查找帧起始位置
                int startIndex = -1;
                for (int i = 0; i < mDataBuffer.size(); i++) {
                    if (mDataBuffer.get(i) == SpectrophotometerProtocol.FRAME_HEADER) {
                        startIndex = i;
                        break;
                    }
                }

                // 没有找到起始帧，清空缓冲区
                if (startIndex == -1) {
                    mDataBuffer.clear();
                    return;
                }

                // 查找帧结束位置（在起始位置之后）
                int endIndex = -1;
                for (int i = startIndex; i < mDataBuffer.size(); i++) {
                    if (mDataBuffer.get(i) == SpectrophotometerProtocol.FRAME_FOOTER) {
                        endIndex = i;
                        break;
                    }
                }

                // 找到完整帧
                if (endIndex != -1) {
                    // 提取完整帧数据
                    int frameLength = endIndex - startIndex + 1;
                    byte[] frameData = new byte[frameLength];
                    for (int i = 0; i < frameLength; i++) {
                        frameData[i] = mDataBuffer.get(startIndex + i);
                    }

                    // 回调完整帧数据
                    final byte[] validFrame = frameData;
                    mMainHandler.post(() -> {
                        if (callback != null) {
                            callback.onDataReceived(validFrame);
                        }
                    });

                    // 从缓冲区中移除已处理的数据（包括起始位置之前可能存在的无效数据）
                    for (int i = 0; i <= endIndex; i++) {
                        if (!mDataBuffer.isEmpty()) {
                            mDataBuffer.remove(0);
                        }
                    }

                    // 继续检查缓冲区中是否还有完整帧
                    continue;
                }

                // 没有找到完整帧，保留缓冲区中的数据等待后续数据
                break;
            }
        }
    }

    // 回调接口定义
    public interface SerialWriteCallback {
        void onWriteComplete(int bytesWritten);
        void onWriteError(Exception e);
    }

    public interface SerialReadCallback {
        void onDataReceived(byte[] data);
        void onReadError(Exception e);
    }
}